package JWT;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

public class JwtUtil {

    static Logger logger = LoggerFactory.getLogger(JwtUtil.class);

    public static String createToken(Identity identity, String apiKeySecret) {
        //JWT采用的签名算法
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        //获取当前时间戳
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        //封装好加密算法与私钥apiKeySecret
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(apiKeySecret);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
        //采用建造者模式定制化token属性
        JwtBuilder builder = Jwts.builder().setId(identity.getId())
                .setIssuedAt(now)
                .setSubject(identity.getId() + "," + identity.getUserName() + "," + identity.getRole())
                .setIssuer(identity.getIssuer())
                .signWith(signatureAlgorithm, signingKey);
        //设置失效时间戳
        long ttlMillis = identity.getDuration();
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
            identity.setDuration(exp.getTime());
        }
        //生成token并序列化编码成一个URL安全的字符串
        logger.info("token生成成功");
        return builder.compact();
    }

    public static Identity parseToken(String token, String apiKeySecret) throws Exception {
        Claims claims = Jwts.parser()
                .setSigningKey(DatatypeConverter.parseBase64Binary(apiKeySecret))
                .parseClaimsJws(token).getBody();
        String[] subjectInfos = claims.getSubject().split(",");
        String id = subjectInfos[0];
        String userName = subjectInfos[1];
        String role = subjectInfos[2];
        // 封装成pojo
        Identity identity = new Identity();
        identity.setId(id);
        identity.setUserName(userName);
        identity.setRole(role);
        identity.setDuration(claims.getExpiration().getTime());
        logger.info("已登录的用户，有效token");
        return identity;
    }
}
